#include "jservicemanager.h"

#if 0 //以淘汰：被元系统取代

#include <JXQCore/JConcurrent>
#include <JXQCore/JMutex>
#include <JXQCore/JDebug>
#include <map>

namespace JXQ
{

using ServiceFunc = JServiceManager::ServiceFunc;

// 服务存储树（RB-Tree）(可选: 跳跃表、哈希表)
class J_DECL_HIDDEN ServiceTree
{
public:
	bool insert(const JString &serviceName, ServiceFunc &service);
	bool insert(const JString &serviceName, ServiceFunc &&service);

public:
	bool remove(const JString &serviceName);
	ServiceFunc find(const JString &serviceName);

public:
	bool isEmpty() const;
	bool size() const;

private:
	bool insert(const JString &serviceName, ServiceFunc *service);

private:
	std::map<JString, ServiceFunc>  tree;
	mutable std::mutex lock;
};

inline static ServiceTree &serviceTree()
{
	static ServiceTree tree;
	return tree;
}

bool ServiceTree::
insert(const JString &serviceName, ServiceFunc &service)
{
	return insert(serviceName, &service);
}

bool ServiceTree::
insert(const JString &serviceName, ServiceFunc &&service)
{
	return insert(serviceName, &service);
}

bool ServiceTree::
remove(const JString &serviceName)
{
	Q_MUTEX_LOCKER(lock);
	return tree.erase(serviceName) > 0;
}

ServiceFunc ServiceTree::
find(const JString &serviceName)
{
	Q_MUTEX_LOCKER(lock);
	auto it = tree.find(serviceName);
	if( it == tree.end() )
		return nullptr;
	return it->second;
}

bool ServiceTree::isEmpty() const
{
	Q_MUTEX_LOCKER(lock);
	return tree.empty();
}

bool ServiceTree::size() const
{
	Q_MUTEX_LOCKER(lock);
	return tree.size();
}

bool ServiceTree::insert(const JString &serviceName, ServiceFunc *service)
{
	if( serviceName.empty() )
	{
		std::cout << "service name is empty" << std::endl;
		return false;
	}

	if( service == nullptr )
	{
		std::cout << "register service is nullptr" << std::endl;
		return false;
	}

	Q_MUTEX_LOCKER(lock);
	auto it = tree.find(serviceName);
	if( it == tree.end() )
	{
		tree.insert(std::make_pair(serviceName, *service));
		return true;
	}
	return false;
}

class J_DECL_HIDDEN JServiceManagerPrivate
{
public:
	JConcurrent jc;
};

/*------------------------------------------------------------------------------------*/

JServiceManager::JServiceManager() :
	d_ptr(new JServiceManagerPrivate())
{

}

JServiceManager::~JServiceManager()
{
	delete d_ptr;
}

bool JServiceManager::
registerService(const JString &serviceName, ServiceFunc &func)
{
	return serviceTree().insert(serviceName, func);
}

bool JServiceManager::
registerService(const JString &serviceName, ServiceFunc &&func)
{
	return serviceTree().insert(serviceName, std::move(func));
}

bool JServiceManager::
unregisterService(const JString &serviceName)
{
	return serviceTree().remove(serviceName);
}

std::future<JVariant> JServiceManager::
call(const JString &serviceName, const JVariant &arg)
{
	auto func = serviceTree().find(serviceName);
	if( func == nullptr )
	{
		std::cout << "service is not register" << std::endl;
		return std::future<JVariant>();
	}
	return JConcurrent::run(func, arg);
}

std::future<JVariant> JServiceManager::
call(const JString &serviceName, const JVariant &arg, CallBack &callBack)
{
	auto func = serviceTree().find(serviceName);
	if( func == nullptr )
	{
		std::cout << "service is not register" << std::endl;
		return std::future<JVariant>();
	}
	return d_ptr->jc.run(callBack, func, arg);
}

std::future<JVariant> JServiceManager::
call(const JString &serviceName, const JVariant &arg, CallBack &&callBack)
{
	auto func = serviceTree().find(serviceName);
	if( func == nullptr )
	{
		std::cout << "service is not register" << std::endl;
		return std::future<JVariant>();
	}
	return d_ptr->jc.run(std::move(callBack), func, arg);
}

JVariant JServiceManager::
callBlock(const JString &serviceName, const JVariant &arg)
{
	auto func = serviceTree().find(serviceName);
	if( func == nullptr )
	{
		std::cout << "service is not register" << std::endl;
		return JVariant();
	}

	try {
		return func(arg);
	}
	catch(...) {
		std::cout << "JServiceManager::callServiceBlock : call func error" << std::endl;
	}
	return JVariant();
}

int JServiceManager::number()
{
	return serviceTree().size();
}

bool JServiceManager::isEmpty()
{
	return serviceTree().isEmpty();
}

bool JServiceManager::exists(const JString &serviceName)
{
	return serviceTree().find(serviceName) != nullptr;
}

} //namespace JXQ

#endif //以淘汰：被元系统取代
